package
{
	import flash.utils.ByteArray;
	
	public class Reader
	{
		/* Reader for known file formats. */
		
		private static function sub(s:String, a:uint, b:uint):String {
			return s.substring(a-1,b);
		}
		
		/* Reads a PDB file into a Structure. */
		public static function ReadPDB(buffer:ByteArray):Structure {
			var S:Structure = new Structure("UNNAMED");
			
			var PDBContents:ByteArray = new ByteArray(); /* do we actually need to copy it? */
			PDBContents.writeBytes(buffer);
			
			np.debug.print("PDB: Loaded; length: " + PDBContents.length + " bytes.");
			
			var PDBLines:Array = PDBContents.toString().split("\n");
			var currentChain:Array  = new Array(); /* chain under construction */
			var line:String; /* Current line of PDB being parsed. */
			
			//var ch:Chain = new Chain("A", this);
			
			/* TODO!!!!!!!!!!! Trim Whitespace */
			function pdbStr(a:uint, b:uint):String {return sub(line,a,b)}
			
			function pdbInt(a:uint, b:uint):int {return parseInt(sub(line,a,b))}
			function pdbFloat(a:uint, b:uint):Number {return parseFloat(sub(line,a,b))}
			
			/*
			function endChain():void {
				Chains.push(currentChain);
				currentChain = new Array();
			}
			*/
			
			//var lastChain:String = "";
			for each (line in PDBLines) {
				var hetFlag:Boolean = false;
				switch (pdbStr(1,6)) { /* TODO: error detection? */
					case "HEADER":
						S.Meta["classification"] = pdbStr(11,50);
						S.Meta["depDate"] = pdbStr(51,59);
						S.Meta["idCode"] = pdbStr(63,66);
						break;
					case "TITLE ":
						S.Meta["continuation"] = pdbStr(9,10);
						S.Name = pdbStr(11,80); /* S.Meta["title"] = pdbStr(11,80); */
						break;
					case "HETATM":
						hetFlag = true; /* and continue down */
					case "ATOM  ":
						//if (pdbStr(22,22) != lastChain) endChain(); /* Needed if TER was omitted. */
						
						var serial:uint = pdbInt(7,11); /* serial number */
						var name:String = pdbStr(13,16); /* name: e.g. C, CA, CB, N, H, ... */
						var altLoc:String = pdbStr(17,17); /* alternate location (not used by MOE?) */
					    var resName:String = pdbStr(18,20) /* residue this atom is part of */
						var chainID:String = pdbStr(22,22); /* chain identifier */
						var resSeq:uint = pdbInt(23,26); /* sequence number of this residue */
						var iCode:String = pdbStr(27,27); /* code for insertion of residue (not used by MOE?) */
						var x:Number = pdbFloat(31,38); /* position in space */
						var y:Number = pdbFloat(39,46); /* position in space */
						var z:Number = pdbFloat(47,54); /* position in space */
						var occupancy:Number = pdbFloat(55,60); /* Occupancy */
						var tempFactor:Number = pdbFloat(61,66); /* Temperature factor */
						var element:String = pdbStr(77,78); /* Element Symbol */
						var charge:String = pdbStr(79,80); /* Charge on the atom. */
						
						
						

						//lastChain = pdbStr(22,22); /* Needed if TER was omitted. */
						break;
					case "TER   ":
						//endChain(); /* Chain explicitly terminated. Not always the case. */
						break;
					default:
						/* TODO: Other tags... */
						break;
				}
			}
			
			//DumpSequence(0);
			return S;
		}



	}
}